﻿/*
-----------------------------------------------------------------------------
This source file is part of Cell Cloud.

Copyright (c) 2009-2012 Cell Cloud Team - cellcloudproject@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#ifndef CellWorkChain_h
#define CellWorkChain_h

#include "CellPrerequisites.h"
#include "CellSection.h"
#include "CellThread.h"

namespace cell
{
/** \addtogroup Core
 *  @{
 */
/** \addtogroup General
 *  @{
 */

class HeadSection;
class TailSection;
class ChainThread;

/** 工作链。
@author
	Jiangwei Xu
*/
class _CellExport WorkChain : public GeneralAlloc
{
public:
	/** 默认构造函数。
	*/
	WorkChain(const String& name);

	/** 析构函数。
	*/
	virtual ~WorkChain(void);

public:
	/** 链接体。
	*/
	class _CellExport Entry : public GeneralAlloc
	{
	public:
		/** 构造函数。
		*/
		Entry(WorkChain* chain, Entry* prevEntry, Entry* nextEntry, Section* section);

		/** 析构函数。
		*/
		virtual ~Entry(void);

	public:
		/** 返回任务段。
		*/
		Section* getSection(void);

		/** 返回下一任务段。
		*/
		NextSection* getNextSection(void);

	private:
		Entry* mPrevEntry;
		Entry* mNextEntry;

		Section* mSection;
		NextSection* mNextSection;

		friend class NextSection;
		friend class WorkChain;
	};

	typedef HashMap<String, WorkChain::Entry*> EntryMap;

public:
	/** 返回链名称。
	*/
	inline const String& getName(void) const { return mName; }

	/** 返回指定的链接体。
	*/
	WorkChain::Entry* getEntry(const String& name);

	/** 返回指定的任务段。
	*/
	Section* get(const String& name);

	/** 在最后一个任务段后追加任务段。
	*/
	void append(Section* section);

	/** 将指定任务段添加为第一个。
	*/
	void addFirst(Section* section);

	/** 将指定任务段添加为最后一个。
	*/
	void addLast(Section* section);

	/** 在指定段前添加新的任务段。
	*/
	void addBefore(Section* base, Section* section);

	/** 在指定段前添加新的任务段。
	*/
	void addBefore(const String& baseName, Section* section);

	/** 在指定段后添加新的任务段。
	*/
	void addAfter(Section* base, Section* section);

	/** 在指定段后添加新的任务段。
	*/
	void addAfter(const String& baseName, Section* section);

	/** 移除指定任务段。
	*/
	void remove(const String& name);

	/** 使用新段替换已存在的段。
	*/
	Section* replace(const String& name, Section* newSection);

	/** 判断指定名称的任务段是否存在。
	*/
	bool exists(const String& name);

	/** 启动任务。
	*/
	void fire(void);

	/** 返回当前工作的任务段。
	*/
	inline Section* getCurrentSection(void) const { return mCurrentEntry->getSection(); }

	/** 是否执行完毕所有的任务段。
	*/
	inline bool hasAllSectionsFired(void) const { return mDone; }

private:
	/** 检查是否可添加指定名称的任务段。
	*/
	bool checkAddable(const String& name);

	/** 添加链接体。
	*/
	void addEntry(Entry* prevEntry, Section* section);

	/** 移除链接体。
	*/
	void removeEntry(const String& name);

private:
	String mName;

	/// 链头
	Entry* mHead;
	HeadSection* mHeadSection;

	/// 链尾
	Entry* mTail;
	TailSection* mTailSection;

	Entry* mCurrentEntry;

	// 执行完毕标示
	bool mDone;

	EntryMap mEntries;

	friend class TailSection;
	friend class NextSection;
};


/** 任务节点的下一个任务节点引入元素。
@author
	Jiangwei Xu
*/
class _CellExport NextSection : public GeneralAlloc
{
private:
	/** 默认构造函数。
	*/
	NextSection(void);

public:
	/** 构造函数。
	*/
	NextSection(WorkChain* chain, WorkChain::Entry* entry);

	/** 析构函数。
	*/
	virtual ~NextSection(void);

public:
	/** 返回其所属的链。
	*/
	inline WorkChain* getChain(void) { return mChain; }

	/** 接力进入下一任务段。
	*/
	void relay(void);

private:
	WorkChain* mChain;
	WorkChain::Entry* mEntry;
};


/** 内置头任务段。
@author
	Jiangwei Xu
*/
class _CellPrivate HeadSection : public Section
{
public:
	/** 构造函数。
	*/
	HeadSection(WorkChain* chain);

	/** 析构函数。
	*/
	virtual ~HeadSection(void);

public:
	/** 当进入该任务段时被调用。
	*/
	void relayed(NextSection* nextSection);
};


/** 内置尾任务段。
@author
	Jiangwei Xu
*/
class _CellPrivate TailSection : public Section
{
public:
	/** 构造函数。
	*/
	TailSection(WorkChain* chain);

	/** 析构函数。
	*/
	virtual ~TailSection(void);

public:
	/** 当进入该任务段时被调用。
	*/
	void relayed(NextSection* nextSection);
};

/** 链启动线程。
@author
	Jiangwei Xu
*/
class _CellPrivate ChainThread : public Thread
{
public:
	/**
	*/
	ChainThread(void);

	/**
	*/
	virtual ~ChainThread(void);

public:
	/**
	*/
	void run(void);
};

/** @} */
/** @} */
} // end namespace cell

#endif // CellWorkChain_h
